package world3d.world.entities;

import com.jogamp.opengl.util.texture.Texture;
import com.sun.scenario.effect.impl.BufferUtil;
import world3d.world.Entity;

import javax.imageio.ImageIO;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.glu.GLU;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.nio.ByteBuffer;

public class SphereOnXYEntity2 extends Entity {
	private GLU glu;
	private static final int rgba = 4;
	private static final int checkImageWidth = 64;
	private static final int checkImageHeight = 64;
	private int[] texName = new int[2];
	private ByteBuffer checkImageBuf = getOtherImageBuf();//
//			BufferUtil.newByteBuffer(checkImageWidth * checkImageHeight * rgba);
	private ByteBuffer otherImageBuf = //getOtherImageBuf();//
			BufferUtil.newByteBuffer(checkImageWidth * checkImageHeight * rgba);


	public SphereOnXYEntity2() {
//		x = y = z = 0;
//		checkImageBuf.rewind();
	}

	public SphereOnXYEntity2(double x, double y, double z) {
//		this.x = x;
//		this.y = y;
//		this.z = z;
	}

	@Override
	public void display() {
		GL2 gl = drawable.getGL().getGL2();

		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		gl.glBindTexture(GL.GL_TEXTURE_2D, texName[0]);
		gl.glBegin(GL2.GL_QUADS);
		gl.glTexCoord2d(0.0, 0.0);
		gl.glVertex3d(-2.0, -1.0, 0.0);
		gl.glTexCoord2d(0.0, 1.0);
		gl.glVertex3d(-2.0, 1.0, 0.0);
		gl.glTexCoord2d(1.0, 1.0);
		gl.glVertex3d(0.0, 1.0, 0.0);
		gl.glTexCoord2d(1.0, 0.0);
		gl.glVertex3d(0.0, -1.0, 0.0);
		gl.glEnd();
		gl.glBindTexture(GL2.GL_TEXTURE_2D, texName[1]);
		gl.glBegin(GL2.GL_QUADS);
		gl.glTexCoord2d(0.0, 0.0);
		gl.glVertex3d(1.0, -1.0, 0.0);
		gl.glTexCoord2d(0.0, 1.0);
		gl.glVertex3d(1.0, 1.0, 0.0);
		gl.glTexCoord2d(1.0, 1.0);
		gl.glVertex3d(2.41421, 1.0, -1.41421);
		gl.glTexCoord2d(1.0, 0.0);
		gl.glVertex3d(2.41421, -1.0, -1.41421);
		gl.glEnd();
		gl.glFlush();
	}

	@Override
	public void init(GLAutoDrawable glAutoDrawable) {
		super.init(glAutoDrawable);
		GL2 gl = glAutoDrawable.getGL().getGL2();
		glu = new GLU();

		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.glShadeModel(GL2.GL_FLAT);
		gl.glEnable(GL.GL_DEPTH_TEST);

		makeCheckImages();

		gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);

		gl.glGenTextures(2, texName, 0);
		gl.glBindTexture(GL.GL_TEXTURE_2D, texName[0]);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
				GL.GL_NEAREST);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
				GL.GL_NEAREST);
		gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, checkImageWidth,
				checkImageHeight, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, otherImageBuf);

		gl.glBindTexture(GL.GL_TEXTURE_2D, texName[1]);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
				GL.GL_NEAREST);
		gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
				GL.GL_NEAREST);
		gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_DECAL);
		gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, checkImageWidth,
				checkImageHeight, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, otherImageBuf);
		gl.glEnable(GL.GL_TEXTURE_2D);
	}

	private ByteBuffer getOtherImageBuf() {
		try {
			BufferedImage image = ImageIO.read(getClass().getClassLoader().getResource("earth_texture.jpg"));
			DataBufferByte dbb = (DataBufferByte)image.getRaster().getDataBuffer();
			byte[] data = dbb.getData();
			ByteBuffer pixels = BufferUtil.newByteBuffer(data.length);
			pixels.put(data);
			pixels.flip();
//			gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, 256, 256, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, pixels);
			return pixels;
		} catch(Throwable t) {
			t.printStackTrace();
		}
		return otherImageBuf;
	}

	@Override
	public void reshape(int x, int y, int width, int height) {
		GL2 gl = drawable.getGL().getGL2();

		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL2.GL_PROJECTION);
		gl.glLoadIdentity();
		glu.gluPerspective(60.0, (float) width / (float) height, 1.0, 30.0);
		gl.glMatrixMode(GL2.GL_MODELVIEW);
		gl.glLoadIdentity();
		gl.glTranslated(0.0, 0.0, -3.6);
	}

	private void makeCheckImages() {
		byte c = 0x00;

		for (int i = 0; i < checkImageWidth; i++) {
			for (int j = 0; j < checkImageHeight; j++) {

				c = (byte) ((((byte) ((i & 0x8) == 0 ? 0x00 : 0xff)//
						^ (byte) ((j & 0x8) == 0 ? 0x00 : 0xff))));
				// checkImage[i][j][0] = (byte) c;
				// checkImage[i][j][1] = (byte) c;
				// checkImage[i][j][2] = (byte) c;
				checkImageBuf.put((byte) c);
				checkImageBuf.put((byte) c);
				checkImageBuf.put((byte) c);
				checkImageBuf.put((byte) 0xff);

				c = (byte) ((((byte) ((i & 0x10) == 0 ? 0x00 : 0xff)//
						^ (byte) ((j & 0x10) == 0 ? 0x00 : 0xff))));

				otherImageBuf.put((byte) c);
				otherImageBuf.put((byte) 0);
				otherImageBuf.put((byte) 0);
				otherImageBuf.put((byte) 0xff);
			}
		}
		checkImageBuf.rewind();
		otherImageBuf.rewind();
	}

	@Override
	public void dispose() {

	}
}
